package TestSuite;

import java.io.File;
import java.util.Random;

import bosVM2.Engine.ExecutionEngine;
import bosVM2.Engine.Frames.MethodFrame;
import bosVM2.meta.Objects.BosMethod;

public aspect AInjector {

	Random rnd = new Random(); //Random seeded value used for fault injection possibility
	Injector inj = new Injector();
	Logger logger = new Logger();
	boolean log = true; //Used to enable/disable logging
	
	//__________________Pointcuts_______________________________________________________
	
	pointcut MethodFrame(): //used for injecting fault at every instruction
		call(MethodFrame getMethodFrame());
	
	pointcut logging(): //used for logging purposes
		call(void handleOpcodeFault(int, BosMethod, ExecutionEngine )) ||
		call(void handleAritcodeFault(int, BosMethod, ExecutionEngine)) ||
		call(void handleIfcodeFault(int, BosMethod, ExecutionEngine)) ||
		call(int handleValueFault(int, int)) ||
		call(char[] correctBitFlip(int ,char[]))||
		call(void mapKeyErrorCorrection(Object[])) ||
		call(void methodsMapKeyErrorCorrection(Object[])) ||
		call(void fieldsMapKeyErrorCorrection(Object[]));
		
	pointcut done(): //used to finish the log with statistics
		call(void execute());
	
	
	//__________________Advice__________________________________________________________
	
	//Advice that creates a possibility of injecting a fault
	after() returning(MethodFrame m): MethodFrame()
	{
		int i = rnd.nextInt(10000);
		if(i < bosVM2.bin.bin.faultRate)
		{
			//injects a fault of random type
			inj.inject(m);
		} 
	}
	
	
	//Creates the end of the log
	after(): done()
	{
		if(log == true)
		{
			logger.generateLogEnd();
			
		}
	}
	
	//gathers information about values before correction for logging purposes
	/*before(): logging()
	{
		if(log == true)
		{	
			logger.getOldValue(thisJoinPoint.getThis(), thisJoinPoint.toString(), thisJoinPoint.getArgs());	
		}
	}*/
	
	
	//Creates log entry for opcode faults
	after(): logging()
	{
		if(log == true)
		{
			logger.generateLogEntry(thisJoinPoint.toString());
		}
	}
	
	//Creates log entry for value faults
	/*after() returning(int i): logging()
	{
		if(log == true)
		{
			logger.generateLogEntry(thisJoinPoint.toString(), thisJoinPoint.getThis(), i);
		}
	}
	
	after() returning(char[] c): logging()
	{
		logger.generateLogEntry(thisJoinPoint.toString(), c);
	}*/
	
}
